package client

import (
	"encoding/json"
	"errors"
	"fmt"
	"fssh/binaryfile"
	"io"
	"log"
	"os"
	"runtime"

	"golang.org/x/crypto/ssh"
)

//Config 配置项
type Config struct {
	Host     string
	Username string
	Password string
	Port     int
	Alias    string
}

//SSHResult  结果
type SSHResult struct {
	Stderr string
	Stdout string
}

var hosts map[string]Config
var saveFileName string

var file binaryfile.File = binaryfile.File{
	Path: "./data",
	Key:  "fssh.pwds",
}

func init() {
	hosts = map[string]Config{}
	logFile, err := os.OpenFile("./client.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("open log file failed, err:", err)
		return
	}
	log.SetOutput(logFile)
	err = file.Read()
	if err != nil {
		log.Println("read file error", err)
	} else {

		err = json.Unmarshal(file.Content, &hosts)
		if err != nil {
			log.Println("decode json error ", err)
		}
	}

}

//Add 添加
func Add(key string, info Config) error {
	hosts[key] = info

	jsonstr, err := json.Marshal(hosts)
	if err != nil {
		log.Println("encode json error ", err)
	}

	file.Content = []byte(jsonstr)
	err = file.Save()
	if err != nil {
		log.Println("save error ", err)
		return err
	}
	return nil
}

//All 获取全部
func All() map[string]Config {
	return hosts
}

//Find 获取一个
func Find(key string) (Config, error) {
	value, isexist := hosts[key]
	if isexist {
		return value, nil
	}
	return Config{}, errors.New("不存在此配置项")
}

//Connect 连接
func (cfg Config) Connect() {
	address := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
	clientCfg := ssh.ClientConfig{
		User:            cfg.Username,
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Auth:            []ssh.AuthMethod{ssh.Password(cfg.Password)},
	}

	client, err := ssh.Dial("tcp", address, &clientCfg)
	defer client.Close()
	if err != nil {
		log.Fatalln(err)
	}

	session, err := client.NewSession()

	if err != nil {
		log.Fatalln(err)

	}
	defer session.Close()

	out, err := session.StdoutPipe()
	if err != nil {
		log.Fatalln(err)
	}
	go func() {
		var buf [65 * 1024]byte
		for {
			i, err := out.Read(buf[0:])
			if err == io.EOF {
				break
			}
			if err != nil {
				fmt.Println(err)
			}
			//fmt.Println(string(buf[i-2]))
			fmt.Print(string(buf[:i]))

		}
	}()

	session.Stderr = os.Stderr // 会话错误输出关联到系统标准错误输出设备
	session.Stdin = os.Stdin   // 会话输入关联到系统标准输入设备
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,     // 禁用回显（0禁用，1启动）
		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
		ssh.TTY_OP_OSPEED: 14400, //output speed = 14.4kbaud
	}

	if err = session.RequestPty(runtime.GOOS, 80, 240, modes); err != nil {
		log.Fatalln(err)
		return
	}

	if err = session.Shell(); err != nil {
		log.Fatalln(err)
		return
	}

	if err = session.Wait(); err != nil {
		log.Fatalln(err)
		return
	}

}
